package com.faner4cloud.yun.service.impl;

import com.faner4cloud.yun.service.ThreadPoolService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author ...zz
 * @version v1
 * @summary desc
 * @since 2022/7/11 2:34 PM
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ThreadPoolServiceImpl implements ThreadPoolService {

	@Resource(name = "linked")
	private ExecutorService linked;

	/**
	 * 使用异步注解 @Async
	 * 使用自定义线程池 {@link com.faner4cloud.yun.common.config.TaskExecutorConfiguration}
	 */
	@Async
	@Override
	public void useAsyncExec() {
		for (int i = 0; i < 100; i++) {
			for (int j = 0; j < 1000; j++) {
				log.info(Thread.currentThread().getName() + "--" + i+ "--" +j);
			}
		}
	}

	/**
	 * 多线程并发执行阻塞等待获取结果
	 */
	@Override
	public void blockAsyncExec() {
		AtomicInteger success = new AtomicInteger();
		AtomicInteger failed = new AtomicInteger();
		// 用于判断所有的线程是否结束
		final CountDownLatch latch = new CountDownLatch(5);
		for (int i = 0; i < 5; i++) {
			// 内部类里i不能直接用,所以赋值给n
			final int n = i;
			Runnable run = () -> {
				log.info(Thread.currentThread().getName());
				try {
					if (n % 2 == 0) {
						success.getAndIncrement();
					} else {
						failed.getAndIncrement();
					}
				} finally {
					latch.countDown();
				}
			};
			linked.execute(run);
		}
		try {
			// 等待所有线程执行完毕
			latch.await();
		} catch (InterruptedException e) {
			log.error("e", e);
			Thread.currentThread().interrupt();
		}
		log.info("success=="+ success.get());
		log.info("failed=="+ failed.get());
	}
}
